	TITLE	'FILE NAME SCANNER'
	PAGEWIDTH 110

	CSEG

;PROGRAMMED BY A. L. BENDER, M. D.
;NEUROLOGICAL SERVICES, INC.
;WESTWOOD NJ 07675
;THIS MAY BE USED FREELY BY ANYONE BUT THE ABOVE "BYLINE"
;MUST REMAIN UNCHANGED

	PUBLIC	FSCAN
;
;enter with:
;	DX-->FCB ADDRESS
;	BX-->STRING TO CONVERT
;	DS:=>BOTH DX AND BX
;	CALL	FSCAN:NEAR
;
;EXIT WITH:
;	AL=0 AND Z FLAG SET MEANS NO ERROR OCCURRED DURING SCAN
;	AH IS DESTROYED.
;	DIRECTION FLAG IS CLEARED
;	BX=>LAST CHARACTER SCANNED (THE ONE THAT STOPPED THE SCAN)
;	DX=>POINTS TO YOUR FCB AS ON ENTRY
;	ALL OTHER REGISTERS EXCEPT PSW ARE PRESERVED
;	AL=NON ZERO AND ZFLAG CLEAR MEANS ERROR DURING SCAN
;
;	SCAN STOPS ON COMMA, SEMICOLON, EQUALS SIGN, BLANK, CARRIAGE
;		RETURN, LEFT BRACKET, LESS THAN SIGN, ZERO (NULL).
;	ON EXIT THE FCB IS ALL SET UP TO USE (THE BODY IS ZEROIZED
;	AND THE FILENAME, DISK AND EXTENSION ARE SET FOR USE)
;
;	YOU MAY WISH TO MAKE THIS A "FAR" PROCEDURE.  TO DO THIS YOU
;	MUST CALL IT FSCAN END EXTERNALIZE IT ":FAR".  CHANGE THE
;	RETURN FOLLOWING THE LABEL "EXIT" TO "RETF" RATHER THAN "RET"
;
;	THIS SUBROUTINE USES NO OTHER SUBROUTINES.
;
;
FCBLEN	EQU	36	;SIZE OF FILE CONTROL BLOCK
FNAMEL	EQU	8	;LENGTH OF FILENAME (PRIMARY NAME)
FEXTL	EQU	3	;LENGTH OF FILE EXTENSION
FNLEN	EQU	FNAMEL+FEXTL
FSPEC	EQU	FNLEN+1	;FILE AND DISK SIZE
FSCAN:	PUSH	CX
	PUSH	ES
	PUSH	SI
	PUSH	DI
	CLD
	MOV	AX,DS
	MOV	ES,AX
	MOV	CX,(FCBLEN-FSPEC)/2	;SOZE OF FCB TO BE ZEROED
	MOV	DI,DX			;FCB ADDRESS
	ADD	DI,FSPEC		;START OF FCB BEYOND FN
	XOR	AX,AX
	REP STOSW			;ZERO FCB
	MOV	DI,DX
	MOV	CX,FSPEC/2
	MOV	AX,'  '			;BLANK OUT FILE NAME IN FCB
	REP STOSW
	MOV	SI,DX
	MOV	BYTE PTR 0 [SI],0	;ZERO DISK INDICATOR
	CMP	BYTE PTR 1[BX],':'	;LOOK FOR EXPLICIT DISK
	JNE	NODISK			;NONE
	MOV	AL,BYTE PTR 0 [BX]	;GET START OF STRING
	CALL	UPPERCASE		;TRANSLATE TO UPPER CASE
	JNZ	ERROR			;ERROR... NOT A LETTER
	SUB	AL,'A'-1		;FORM DISK ID
	MOV	BYTE PTR 0 [SI],AL	;SAVE DISK ID
	INC	BX			;PASS ':'
	INC	BX			;
NODISK:	MOV	CX,FNAMEL	;FILE NAME SIZE
NOD1:	MOV	AL,BYTE PTR 0 [BX]	;GET FIRST CHARACTER OF FILE NAME
	CALL	UPPERCASE		;TRANSLATE TO UC
	JNZ	NOTLET			;NOT A LETTER - SPECIAL
NOD2:	INC	SI
	INC	BX			;MOVE POINTERS ALONG
	MOV	BYTE PTR 0 [SI],AL	;PUT CHARACTER IN FCB
	LOOP	NOD1		;LOOP THRU FILE NAME
NOD3:	MOV	AL,BYTE PTR 0 [BX]	;GET NEXT CHARACTER IN IMAGE
	CMP	AL,'.'		;MUST BE PERIOD OR TERMINATOR
	JZ	FEXT		;FILE EXTENSION
	CALL	TERM		;CHECK FOR TERMINATOR
	JZ	DONE		;TERMINATOR
ERROR:	MOV	AL,1		;IMPROPER FILE SYNTAX
	JMPS	EXIT
DONE:	XOR	AL,AL
EXIT:	OR	AL,AL
	POP	DI
	POP	SI
	POP	ES
	POP	CX
	RET			;RETURN TO USER PROGRAM


NOTLET:	CMP	AL,'*'		;IS IT ASTERISK?
	JZ	NOL1		;YES
	CMP	AL,'.'		;FIND PERIOD?
	JZ	FEXT		;YERP ->PROCESS EXTENSION
	CALL	TERM		;CHECK FOR TERMINATOR CHARACTER
	JZ	DONE		;FINISHED SCAN
	JMPS	NOD2
NOL1:	INC	BX		;POINT TO NEXT CHARACTER IN STRING
	CALL	STAR		;CONVERT *-->???
	JMPS	NOD3		;KILL REMAINDER OF FILENAME PROCESSING

FEXT:	MOV	CX,FEXTL	;SET FOR MAX 3 CHARACTER EXTENSION
	INC	BX		;PASS THE '.'
	MOV	SI,FNAMEL	;BIAS FOR EXTENSION
	ADD	SI,DX		;ADD FCB START (FORM LOC OF EXTENSION)
FX1:	MOV	AL,BYTE PTR 0 [BX]
	CALL	UPPERCASE
	JNZ	SPCH		;SPECIAL CHARACTER
FX2:	INC	BX
	INC	SI
FX3:	MOV	BYTE PTR 0 [SI],AL
	LOOP	FX1
	MOV	AL,BYTE PTR 0 [BX]
	CALL	TERM
	JZ	DONE		;FINISHED WITH SCAN
	JMPS	ERROR		;SCAN ENDED IMPROPERLY
SPCH:	CMP	AL,'*'
	JNZ	SPCH1		;NOT ASTERISK
	CALL	STAR
	INC	BX
	MOV	AL,BYTE PTR 0 [BX]
	CALL	TERM
	JZ	DONE
	JMPS	ERROR
SPCH1:	CALL	TERM
	JNZ	FX2		;NOT TERMINATOR, JUST STORE IT
	JMPS	DONE		;SCAN TERMINATED

;CHECK FOR CHARACTER WHICH WILL TERMINATE D:F.E PROCESSING
TERM:	CMP	AL,','		;CHECK FOR COMMA SEPARATOR
	JZ	T1		;NOPE
	TEST	AL,AL		;CHECK FOR NULL (END OF STRING MARK)
	JZ	T1		;NOPE
	CMP	AL,' '		;TEST BLANK
	JZ	T1		;EXIT IF BLANK
	CMP	AL,0DH		;CARRIAGE RETURN?
	JZ	T1		;NOPE FALL THRU
	CMP	AL,';'		;SEMICOLON?
	JZ	T1
	CMP	AL,'='		;EQUAL SIGN?
	JZ	T1
	CMP	AL,'['
	JZ	T1
	CMP	AL,'<'
T1:	RET			;RETURN WITH FLAGS SET

;CONVERT THE '*' TO PROPER NUMBER OF ??? IN FCB

STAR:	MOV	AL,'?'		;CONVERT '*' TO '???..' IN FN OR FEXT
	INC	SI		;MAKE SI POINT TO STAR FIELD
	MOV	DI,SI
	REP STOSB		;REPEATEDLY STORE ? IN FCB
	MOV	SI,DI		;MAKE SI POINT TO PROPER SPOT IN FCB
	RET			;CX=COUNT OF REMAINDER OF FCB FIELD

UPPERCASE:
	CMP	AL,'A'
	JC	LESS		;LESS THAN CAPITAL A
	CMP	AL,'Z'+1
	JNC	NOTAZ		;NOT A-Z, MAY NEED CONVERSION
LETR:	XOR	AH,AH		;SIGNAL LETTER FOUND (Z=1 ON RETURN)
	RET			;EXIT TO USER
NOTAZ:	CMP	AL,'a'		;CHECK a-z
	JC	LESS		;DONT CONVERT
	CMP	AL,'z'+1
	JNC	LESS		;NOT a-z, DONT CONVERT IT
	AND	AL,01011111B	;MASK UC BIT OUT
	JMPS	LETR		;LETTER RETURN
LESS:	OR	AH,1		;INDICATE NON LETTER
	RET			;RETURN TO USER
	END
